// ListControls.cpp
#define _WIN32_DCOM    // For CoInitializeEx
#include <iostream.h>  // For cout
#include <comcat.h>    // For component category stuff

void main(int argc, char** argv)
{
	cout << "Component: CoInitializeEx()" << endl;
	CoInitializeEx(NULL, COINIT_MULTITHREADED);

	// Instantiate COM's implementation of component categories
	// Ask for ICatInformation
	ICatInformation* pCatInformation;
	CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatInformation, (void**)&pCatInformation);

	// Get an enumerator for all CLSIDs that are Control objects
	IEnumCLSID* pEnumCLSID;
	pCatInformation->EnumClassesOfCategories(1, (CATID*)&CATID_Control, 0, NULL, &pEnumCLSID);

	// Release the ICatInformation interface pointer
	pCatInformation->Release();

	// Loop through the enumerator
	CLSID clsid = CLSID_NULL;
	DWORD fetched = 0;
	DWORD dwSize = 1024;
	char szName[1024];
	HKEY hKey = 0;
	char szKeyBuf[100];

	while(true)
	{
		// Get the next CLSID
		pEnumCLSID->Next(1, &clsid, &fetched);
		if(fetched == 0)
			break;

		// Convert the CLSID to a string for display
		char buffer[39];
		OLECHAR ppsz[39];
		StringFromGUID2(clsid, ppsz, 39);
		WideCharToMultiByte(CP_ACP, 0, ppsz, 39, buffer, 39, NULL, NULL);

		// Copy keyname into buffer.
		strcpy(szKeyBuf, "CLSID\\");
		strcat(szKeyBuf, buffer);

	    HRESULT hr = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyBuf, 0, KEY_READ, &hKey);
	    if(FAILED(hr))
			cout << "Couldn't open the CLSID key" << endl;

	    // Read the value from the registry
		hr = RegQueryValueEx(hKey, NULL, NULL, NULL, (unsigned char*)szName, &dwSize);
		if(FAILED(hr))
		    cout << "Couldn't read the registry value" << endl;

		cout << szName << ": " << szKeyBuf << endl;

		RegCloseKey(hKey);
	}

	// Release the enumerator
	pEnumCLSID->Release();

	CoUninitialize();
}